package cn.edu.gzhmt.goods.admin.web.servlet;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.edu.gzhmt.category.admin.service.IAdminCategoryService;
import cn.edu.gzhmt.category.admin.service.impl.AdminCategoryServiceImpl;
import cn.edu.gzhmt.category.domain.Category;
import cn.edu.gzhmt.goods.admin.service.IAdminGoodsService;
import cn.edu.gzhmt.goods.admin.service.impl.AdminGoodsServiceImpl;
import cn.edu.gzhmt.goods.domain.Goods;
import cn.edu.gzhmt.utils.commons.CommonUtils;

/**
 * 添加商品
 * 添加商品时，需要用到图片上传
 * @author azhuo
 *
 */
public class AdminAddGoodsServlet extends HttpServlet {

	private IAdminCategoryService adminCategoryService = new AdminCategoryServiceImpl();
	private IAdminGoodsService adminGoodsService = new AdminGoodsServiceImpl();

	/**
	 * 添加商品
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		/*
		 * 1、得到工厂：DiskFileItemFactory
		 * 2、根据工厂创建解析器：ServletFileUpload
		 * 3、使用解析器进行解析response得到一个List<FileItem>集合
		 * 4、遍历List<FileItem>集合，利用API完成文件保存
		 * */
		// 1、得到工厂
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// DiskFileItemFactory factory = new DiskFileItemFactory(20*1024, new
		// File("F:/temp"));// 参数：缓存大小、缓存存放路径

		// 2、根据工厂创建解析器
		ServletFileUpload sfu = new ServletFileUpload(factory);
		sfu.setFileSizeMax(500 * 1024); // 限定上传文件大小，必须在parseRequest()之前设置。如果超过限定的大小parseRequest()会抛出异常。
		sfu.setSizeMax(1024 * 1024); // 限制整个表单的大小

		try {
			// 3、使用解析器进行解析request得到一个List<FileItem>集合
			List<FileItem> fileItemList = sfu.parseRequest(request);
			/**
			fileItem {name=null, StoreLocation=, size=8bytes, isFormField=true, FieldName=method}
			fileItem {name=null, StoreLocation=, size=6bytes, isFormField=true, FieldName=gname}
			fileItem {name=null, StoreLocation=, size=4bytes, isFormField=true, FieldName=price}
			fileItem {name=1.png, StoreLocation=, size=3049bytes, isFormField=false, FieldName=image}
			fileItem {name=null, StoreLocation=, size=1bytes, isFormField=true, FieldName=cid}
			fileItem {name=null, StoreLocation=, size=12bytes, isFormField=true, FieldName=parameter}
			fileItem {name=null, StoreLocation=, size=12bytes, isFormField=true, FieldName=desc}
			 */

			// 封装表单中的 字段 数据到实体类中
			Goods formGoods = new Goods();
			formGoods.setGid(CommonUtils.uuid());
			formGoods.setGdel(false);

			// 4、遍历List<FileItem>集合，利用API完成文件保存时
			for (FileItem fileItem : fileItemList) {

				// 判断是否是表单类型数据
				if (fileItem.isFormField()) {

					String fieldName = fileItem.getFieldName(); // 获取表单中的字段名称
					String fieldValue = fileItem.getString("utf-8"); // 获取表单字段中的值

					// 判断是否是商品名称
					if ("gname".equals(fieldName)) {
						formGoods.setGname(fieldValue);

					} else if ("price".equals(fieldName)) {
						// 判断是否是价格
						try {
							formGoods.setPrice(Double.parseDouble(fieldValue));
						} catch (NumberFormatException e) {
							formGoods.setPrice(9.99);
						}
					} else if ("cid".equals(fieldName)) {
						// 判断是否是分类cid
						Category category = adminCategoryService
								.loadCategoryById(fieldValue);

						formGoods.setCid(fieldValue);
						formGoods.setCategory(category);

					} else if ("parameter".equals(fieldName)) {
						// 判断是否是商品参数
						formGoods.setParameter(fieldValue);
					} else if ("desc".equals(fieldName)) {
						// 判断是否是商品描述
						formGoods.setDesc(fieldValue);
					} else if ("promote".equals(fieldName)) {
						// 判断是否是宣传商品类型
						formGoods.setPromote(fieldValue);
					}

				} else {
					// 处理图片

					// 5、保存文件
					// 1）得到文件保存的路径：是保存在项目运行的目录下
					// 获取ServletContext
					String root = this.getServletContext().getRealPath(
							"/image/goods");
					// 2）生成二级目录
					/*
					* （1）得到文件名称
					* （2）得到hashCode
					* （3）转成16进制
					* （4）获取16进制的前两个字符用来生成二级目录
					* */
					// * （1）得到文件名称
					String fileName = fileItem.getName(); // 获取上传文件的文件名称
					// *** 处理文件名的绝对路径问题
					int index = fileName.lastIndexOf("\\");
					if (index != -1) {
						fileName = fileName.substring(index + 1);
					}

					// *** 处理文件名同名问题，给文件名添加uuid前缀
					String savename = CommonUtils.uuid() + "_" + fileName;

					// * （2）得到hashCode
					int hCode = fileName.hashCode();

					// * （3）转成16进制
					String hex = Integer.toHexString(hCode);

					StringBuffer imgDirBuf = new StringBuffer();
					imgDirBuf.append(hex.charAt(0) + "/" + hex.charAt(1));

					// * （4）获取16进制的前两个字符用来生成二级目录
					File dirFile = new File(root, imgDirBuf.toString());
					// *** 创建目录链
					dirFile.mkdirs();

					// 3）创建目录文件
					File destFile = new File(dirFile, savename);

					// 4）保存文件
					fileItem.write(destFile);

					// 获取相对存储路径
					imgDirBuf.append("/" + savename);
					formGoods.setImage(imgDirBuf.toString());
				}

			}
			
			adminGoodsService.addGoods(formGoods);

			List<Goods> goodsList = new ArrayList<Goods>();
			goodsList.add(formGoods);
			request.setAttribute("goodsList", goodsList);

			request.getRequestDispatcher("/adminjsps/goods/findGoods.jsp")
					.forward(request, response);

		} catch (FileUploadException e) {
			if (e instanceof FileUploadBase.FileSizeLimitExceededException) {
				request.setAttribute("msg", "您上传的文件超过了500K");
				request.getRequestDispatcher("/adminjsps/goods/addGoods.jsp").forward(request,
						response);
			}
			throw new RuntimeException(e);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

}
